package com.ai.service;

import com.ai.dao.PrisonerDao;
import com.ai.pojo.ImmsVisiting;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import dev.langchain4j.agent.tool.P;
import dev.langchain4j.agent.tool.Tool;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.Date;

/**
 * @author lgl
 * @description
 * @date 2025/5/20 16:18
 */
@Service
@Slf4j
public class FunctionCallMethodService {

    @Autowired
    private PrisonerDao prisonerDao;

    @Tool("长沙有多少个名字的")
    public Integer changshaNameCount(
            @P("姓名")
            String name) {
        System.out.println(name);
        return 10;
    }

    @Tool("某天某个部门有多少罪犯会见")
    public Integer getDepartmentMeetCount(
            @P("部门名, 数字转换为中文（例如 部门1 转为 部门一）") String areaName,
            @P("时间范围, 格式为 'today', 'yesterday', 'day before yesterday', 'this week', 'this month', 'this year', 'last week', 'last month', 'last year', 'yyyy-MM-dd', 或 'yyyy-MM-dd to yyyy-MM-dd'") String timeRange) {

        log.info("部门名: {}", areaName);
        log.info("时间范围: {}", timeRange);

        if (timeRange == null || timeRange.isEmpty()) {
            log.warn("时间范围参数为空，返回 0");
            return 0;
        }

        try {
            LocalDateTime startOfPeriod;
            LocalDateTime endOfPeriod;
            ZoneId zoneId = ZoneId.systemDefault();
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
            LocalDate today = LocalDate.now();

            // 解析时间范围
            switch (timeRange.toLowerCase()) {
                case "today":
                    startOfPeriod = today.atStartOfDay();
                    endOfPeriod = today.atTime(23, 59, 59, 999999999);
                    break;
                case "yesterday":
                    LocalDate yesterday = today.minusDays(1);
                    startOfPeriod = yesterday.atStartOfDay();
                    endOfPeriod = yesterday.atTime(23, 59, 59, 999999999);
                    break;
                case "day before yesterday":
                    LocalDate dayBeforeYesterday = today.minusDays(2);
                    startOfPeriod = dayBeforeYesterday.atStartOfDay();
                    endOfPeriod = dayBeforeYesterday.atTime(23, 59, 59, 999999999);
                    break;
                case "this week":
                    startOfPeriod = today.with(java.time.temporal.TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY)).atStartOfDay();
                    endOfPeriod = today.with(java.time.temporal.TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY)).atTime(23, 59, 59, 999999999);
                    break;
                case "this month":
                    startOfPeriod = today.withDayOfMonth(1).atStartOfDay();
                    endOfPeriod = today.withDayOfMonth(today.lengthOfMonth()).atTime(23, 59, 59, 999999999);
                    break;
                case "this year":
                    startOfPeriod = today.withDayOfYear(1).atStartOfDay();
                    endOfPeriod = today.withDayOfYear(today.lengthOfYear()).atTime(23, 59, 59, 999999999);
                    break;
                case "last week":
                    LocalDate lastWeek = today.minusWeeks(1);
                    startOfPeriod = lastWeek.with(java.time.temporal.TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY)).atStartOfDay();
                    endOfPeriod = lastWeek.with(java.time.temporal.TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY)).atTime(23, 59, 59, 999999999);
                    break;
                case "last month":
                    LocalDate lastMonth = today.minusMonths(1);
                    startOfPeriod = lastMonth.withDayOfMonth(1).atStartOfDay();
                    endOfPeriod = lastMonth.withDayOfMonth(lastMonth.lengthOfMonth()).atTime(23, 59, 59, 999999999);
                    break;
                case "last year":
                    LocalDate lastYear = today.minusYears(1);
                    startOfPeriod = lastYear.withDayOfYear(1).atStartOfDay();
                    endOfPeriod = lastYear.withDayOfYear(lastYear.lengthOfYear()).atTime(23, 59, 59, 999999999);
                    break;
                default:
                    if (timeRange.contains(" to ")) {
                        // 处理自定义日期范围（例如 "2025-05-18 to 2025-05-21"）
                        String[] dates = timeRange.split(" to ");
                        if (dates.length != 2) {
                            throw new IllegalArgumentException("时间范围格式错误，预期为 'yyyy-MM-dd to yyyy-MM-dd'");
                        }
                        startOfPeriod = LocalDate.parse(dates[0].trim(), formatter).atStartOfDay();
                        endOfPeriod = LocalDate.parse(dates[1].trim(), formatter).atTime(23, 59, 59, 999999999);
                    } else {
                        // 处理单一日期（例如 "2025-05-21"）
                        startOfPeriod = LocalDate.parse(timeRange.trim(), formatter).atStartOfDay();
                        endOfPeriod = LocalDate.parse(timeRange.trim(), formatter).atTime(23, 59, 59, 999999999);
                    }
                    break;
            }

            // 确保结束日期不早于开始日期
            if (endOfPeriod.isBefore(startOfPeriod)) {
                throw new IllegalArgumentException("结束日期不能早于开始日期");
            }

            // 转换为 Date 对象用于查询
            ZoneOffset zoneOffset = zoneId.getRules().getOffset(startOfPeriod);
            Date startDate = Date.from(startOfPeriod.toInstant(zoneOffset));
            Date endDate = Date.from(endOfPeriod.toInstant(zoneOffset));

            // 构建查询
            LambdaQueryWrapper<ImmsVisiting> queryWrapper = Wrappers.lambdaQuery(ImmsVisiting.class)
                    .eq(ImmsVisiting::getStatus, 1)
                    .in(ImmsVisiting::getState, 3, 4, 5, 6, 7)
                    .like(ImmsVisiting::getAreaName, areaName)
                    .ge(ImmsVisiting::getStartTime, startDate)
                    .le(ImmsVisiting::getStartTime, endDate);

            Long count = prisonerDao.selectCount(queryWrapper);
            log.info("查询结果 - 部门: {}, 时间范围: {}, 计数: {}", areaName, timeRange, count);
            return Math.toIntExact(count);

        } catch (DateTimeParseException e) {
            log.error("时间范围格式错误: {}", timeRange, e);
            throw new IllegalArgumentException("时间范围格式错误，预期为 'today', 'yesterday', 'day before yesterday', 'this week', 'this month', 'this year', 'last week', 'last month', 'last year', 'yyyy-MM-dd' 或 'yyyy-MM-dd to yyyy-MM-dd'");
        }
    }
}
